﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using ERP.EquipmentManage.Dtos;
using ERP.ERPModels.EquipmentManage;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace ERP.EquipmentManage
{
    /// <summary>
    /// 维修服务实现
    /// </summary>
    public class RpeairService : ApplicationService, IRpeairService
    {
        private readonly IRepository<Repair, int> _repairRepository;
        private readonly ILogger<RpeairService> _logger;

        public RpeairService(
            IRepository<Repair, int> repairRepository,
            ILogger<RpeairService> logger)
        {
            _repairRepository = repairRepository;
            _logger = logger;
        }

        /// <summary>
        /// 获取维修单分页列表
        /// </summary>
        public async Task<PagedResultDto<RepairDto>> GetListAsync(GetRepairInputDto input)
        {
            var query = await _repairRepository.GetQueryableAsync();

            // 应用筛选条件
            if (!string.IsNullOrWhiteSpace(input.Keyword))
            {
                query = query.Where(x => x.RepairCode.Contains(input.Keyword) ||
                                        x.RepairName.Contains(input.Keyword) ||
                                        x.DeviceCode.Contains(input.Keyword) ||
                                        x.DeviceName.Contains(input.Keyword));
            }

            if (!string.IsNullOrWhiteSpace(input.RepairCode))
            {
                query = query.Where(x => x.RepairCode.Contains(input.RepairCode));
            }

            if (!string.IsNullOrWhiteSpace(input.RepairName))
            {
                query = query.Where(x => x.RepairName.Contains(input.RepairName));
            }

            if (!string.IsNullOrWhiteSpace(input.DeviceCode))
            {
                query = query.Where(x => x.DeviceCode.Contains(input.DeviceCode));
            }

            if (!string.IsNullOrWhiteSpace(input.DeviceName))
            {
                query = query.Where(x => x.DeviceName.Contains(input.DeviceName));
            }

            if (!string.IsNullOrWhiteSpace(input.RepairPersonnel))
            {
                query = query.Where(x => x.RepairPersonnel.Contains(input.RepairPersonnel));
            }

            if (input.DocumentStatus.HasValue)
            {
                query = query.Where(x => x.DocumentStatus == input.DocumentStatus.Value);
            }

            if (input.WarrantyDateStart.HasValue)
            {
                query = query.Where(x => x.WarrantyDate >= input.WarrantyDateStart.Value.Date);
            }

            if (input.WarrantyDateEnd.HasValue)
            {
                query = query.Where(x => x.WarrantyDate <= input.WarrantyDateEnd.Value.Date.AddDays(1));
            }

            if (input.RepairDateStart.HasValue)
            {
                query = query.Where(x => x.RepairDate >= input.RepairDateStart.Value.Date);
            }

            if (input.RepairDateEnd.HasValue)
            {
                query = query.Where(x => x.RepairDate <= input.RepairDateEnd.Value.Date.AddDays(1));
            }

            // 应用排序
            if (!string.IsNullOrWhiteSpace(input.Sorting))
            {
                query = query.OrderBy(input.Sorting);
            }
            else
            {
                query = query.OrderByDescending(x => x.Id);
            }

            var totalCount = await query.CountAsync();
            var items = await query.Skip(input.SkipCount).Take(input.MaxResultCount).ToListAsync();

            var dtos = items.Select(MapToDto).ToList();

            return new PagedResultDto<RepairDto>(totalCount, dtos);
        }

        /// <summary>
        /// 获取维修单详情
        /// </summary>
        public async Task<RepairDto> GetAsync(int id)
        {
            var entity = await _repairRepository.GetAsync(id);
            return MapToDto(entity);
        }

        /// <summary>
        /// 创建维修单
        /// </summary>
        public async Task<RepairDto> CreateAsync(CreateRepairDto input)
        {
            var entity = new Repair
            {
                RepairCode = await GenerateRepairCodeAsync(),
                RepairName = input.RepairName,
                DeviceCode = input.DeviceCode,
                DeviceName = input.DeviceName,
                WarrantyDate = input.WarrantyDate,
                RepairDate = input.RepairDate,
                AcceptanceDate = input.AcceptanceDate,
                RepairResults = input.RepairResults,
                RepairPersonnel = input.RepairPersonnel,
                AcceptancePerson = input.AcceptancePerson,
                DocumentStatus = 0 // 默认状态：待维修
            };

            entity = await _repairRepository.InsertAsync(entity, true);
            _logger.LogInformation("创建维修单成功，ID: {Id}, 维修单编号: {RepairCode}", entity.Id, entity.RepairCode);

            return MapToDto(entity);
        }

        /// <summary>
        /// 更新维修单
        /// </summary>
        public async Task<RepairDto> UpdateAsync(int id, UpdateRepairDto input)
        {
            var entity = await _repairRepository.GetAsync(id);

            entity.RepairName = input.RepairName;
            entity.DeviceCode = input.DeviceCode;
            entity.DeviceName = input.DeviceName;
            entity.WarrantyDate = input.WarrantyDate;
            entity.RepairDate = input.RepairDate;
            entity.AcceptanceDate = input.AcceptanceDate;
            entity.RepairResults = input.RepairResults;
            entity.RepairPersonnel = input.RepairPersonnel;
            entity.AcceptancePerson = input.AcceptancePerson;
            
            if (input.DocumentStatus.HasValue)
            {
                entity.DocumentStatus = input.DocumentStatus.Value;
            }

            entity = await _repairRepository.UpdateAsync(entity, true);
            _logger.LogInformation("更新维修单成功，ID: {Id}", entity.Id);

            return MapToDto(entity);
        }

        /// <summary>
        /// 删除维修单
        /// </summary>
        public async Task DeleteAsync(int id)
        {
            await _repairRepository.DeleteAsync(id);
            _logger.LogInformation("删除维修单成功，ID: {Id}", id);
        }

        /// <summary>
        /// 生成维修单编号
        /// </summary>
        public async Task<string> GenerateRepairCodeAsync()
        {
            var today = DateTime.Now.ToString("yyyyMMdd");
            var prefix = $"WX{today}";

            var query = await _repairRepository.GetQueryableAsync();
            var maxCode = await query
                .Where(x => x.RepairCode.StartsWith(prefix))
                .Select(x => x.RepairCode)
                .OrderByDescending(x => x)
                .FirstOrDefaultAsync();

            var sequence = 1;
            if (!string.IsNullOrEmpty(maxCode) && maxCode.Length > prefix.Length)
            {
                var sequenceStr = maxCode.Substring(prefix.Length);
                if (int.TryParse(sequenceStr, out var lastSequence))
                {
                    sequence = lastSequence + 1;
                }
            }

            return $"{prefix}{sequence:D4}";
        }

        /// <summary>
        /// 映射到DTO
        /// </summary>
        private RepairDto MapToDto(Repair entity)
        {
            return new RepairDto
            {
                Id = entity.Id,
                RepairCode = entity.RepairCode,
                RepairName = entity.RepairName,
                DeviceCode = entity.DeviceCode,
                DeviceName = entity.DeviceName,
                WarrantyDate = entity.WarrantyDate,
                RepairDate = entity.RepairDate,
                AcceptanceDate = entity.AcceptanceDate,
                RepairResults = entity.RepairResults,
                RepairPersonnel = entity.RepairPersonnel,
                AcceptancePerson = entity.AcceptancePerson,
                DocumentStatus = entity.DocumentStatus,
                DocumentStatusText = GetStatusText(entity.DocumentStatus)
            };
        }

        /// <summary>
        /// 获取状态文本
        /// </summary>
        private string GetStatusText(int? status)
        {
            return status switch
            {
                0 => "待维修",
                1 => "维修中",
                2 => "待验收",
                3 => "已完成",
                _ => "未知"
            };
        }
    }
}
